[% setvar title Transparently integrate C<tie> %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Transparently integrate <code>tie</code></p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Nathan Wiger &lt;<a href='mailto:nate@wiger.org'>nate@wiger.org</a>&gt;
  Date: 25 Sep 2000
  Last Modified: 30 Sep 2000
  Mailing List: <a href='mailto:perl6-language-objects@perl.org'>perl6-language-objects@perl.org</a>
  Number: 319
  Version: 2
  Status: Frozen</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p><b>RFC 200</b> proposes many enhancements to <code>tie</code> to make it more
versatile and multipurpose. However, it still relies on using the <code>tie</code>
keyword to create a <code>tie</code>d variable, keeping <code>tie</code> separate.</p>
<p>Python and lots of other languages have figured out how to implement
fully integrated data, operator, and method overloading. Perl should
too, without looking horrendously OO-ish like Python.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<a name='Implicit tie'></a><h2>Implicit <code>tie</code></h2>
<p>This RFC proposes that <code>tie</code> be integrated with Perl from the ground
up, and not remain as a separate concept. Instead, classes that provide
<code>TIE*</code> methods will have them automatically invoked on declaration.
For example:</p>
<pre>   my float $x = 5.3;    # float-&gt;TIESCALAR($x); $x-&gt;STORE(5.3);</pre>
<p>The <code>TIE*</code> methods are called implicitly on variable declaration. So:</p>
<pre>   my packed $a;         # packed-&gt;TIESCALAR($a);
   $a = get_binary;      # $a-&gt;STORE(...);
   $a++;                 # $a-&gt;STORE($a-&gt;PLUS(1));
   undef $a;             # $a-&gt;DESTROY;

   my bigint @b :128bit; # int-&gt;TIEARRAY(@b, '64bit')
   @c = @b;              # empty list passed still
   @b = (1,2);           # @b-&gt;CLEAR(...); @b-&gt;STORE(0,1); ...</pre>
<p>Note that the <code>TIE*</code> methods will only be called if they exist, just
like currently. If a given <code>TIE*</code> method does not exist, then the
appropriate error should be spit out:</p>
<pre>   my Pet @spot = (&quot;fluffy&quot;);
   Can't locate method &quot;TIEARRAY&quot; via package &quot;Pet&quot;</pre>
<p>In this case, the package <code>Pet</code> has declared that it can't handle
arrays, which is just fine. Note that this does <b>not</b> imply all
classes would have to have <code>TIE</code> methods; see further down under the
section on the <code>:autotie</code> package attribute.</p>
<a name='Passing arguments'></a><h2>Passing arguments</h2>
<p>Since many <code>tie</code>d variables require that extra arguments be passed,
this RFC proposes two ways of doing this. Either could be used,
depending on a person's preference:</p>
<a name='The general attribute style'></a><h3>The general attribute style</h3>
<p>In the attribute style, extra arguments are simply specified as
attributes, which are then passed into the <code>TIE*</code> function as
a hashref of values. So this:</p>
<pre>   my Apache::Session %session :Transaction;</pre>
<p>Would be the same as this in Perl 5:</p>
<pre>   tie %session, 'Apache::Session', { Transaction =&gt; 1 };</pre>
<p>A bare attribute is assumed to be a switch and is simply given a value
of &quot;1&quot;. Note that attributes allow you to specify arguments, too, so
this:</p>
<pre>   my Dog $spot :coat('shiny') :bark('rough') :mean;</pre>
<p>Would result in the following call:</p>
<pre>   Dog-&gt;TIESCALAR($spot, { coat =&gt; 'shiny', bark =&gt; 'rough',
                           mean =&gt; 1 });</pre>
<p>This form has the benefit that it makes user-defined variables appear as
transparent as builtins, and also gives the <code>TIE</code> constructors easy
access to the attributes declared.</p>
<a name='The special :tie variable attribute'></a><h3>The special <code>:tie</code> variable attribute</h3>
<p>With this version, you could use a special <code>:tie</code> attribute that would
be passed to the <code>TIE</code> methods verbatim. So this:</p>
<pre>   my Apache::Session %session :tie( { Transaction =&gt; 1 } );</pre>
<p>Would have the same effect as the above. Note that the benefit of this
way is that you can specify an arbitrary list of numbers or other
arguments:</p>
<pre>   my Matrix @a :tie(1,2,3,4,5);</pre>
<p>You could perhaps accomplish that as either:</p>
<pre>   my Matrix @a = (1,2,3,4,5);
   my Matrix @a :values(1,2,3,4,5);  # { values =&gt; [1,2,3,4,5] }</pre>
<p>But TMTOWTDI. Still, this method may not be necessary; the first one
appears to be sufficient by itself.</p>
<a name='Optimization and Inheritance'></a><h2>Optimization and Inheritance</h2>
<p>One of the main goals behind doing something like this is being able to
create custom variable types that can take advantage of optimizations,
and having these variables walk and talk like builtins.</p>
<p>In fact, it is possible that variable declaration and optimization could
be handled through basic inheritance in Perl 6. For example:</p>
<pre>   package var;         # main variable class

   # all the main Perl internal methods are defined, such
   # as TIESCALAR, TIEARRAY, STORE, FETCH, etc

   package int;
   use base 'var';

   # ideas for RFC 303
   use optimize storage =&gt; 16,   # how much space
                growable =&gt; 1,   # can we grow?
                growsize =&gt; 8,   # how much to grow by
                integer =&gt; 1,    # support ints
                string =&gt; undef, # but not strings
                float =&gt; undef,  # or floats
                promote =&gt; 'bigint';  # promote to class
                                      # when outgrow

   # TIESCALAR, STORE, etc need not be redefined, since
   # they could simply inherit from var's, but perhaps
   # we could define special math ops per RFC 159.</pre>
<p>In this example, we've used the <code>int</code> class to define several key
optimizations for Perl to use. Since <code>var</code> is the grandfather class of
all variables, its <code>STORE</code> and <code>FETCH</code> methods can be used, which
actually do the internals of storing values and using the hints set by
the <code>use optimize</code> pragma. Here, the <code>use optimize</code> pragma should be
localizable and also inheritable, specifying characteristics for the
package itself.</p>
<p>In reality, builtin types will be implemented in C and not Perl.
However, that doesn't mean that other custom classes couldn't still
inherit from these types as well. For example:</p>
<pre>   package CoolInt;      # my own, real cool int
   use base 'int';
   # setup all my methods and optimizations</pre>
<p>So, dispatch for builtin types could be very fast - the correct <code>STORE</code>
et al methods (written in C) are simply called. Then, user-defined types
would be derivable from builtin types with some slowdown, but nowhere
near as bad as <code>tie</code>. Code could simply look like this:</p>
<pre>   use CoolInt;
   my CoolInt $x = 42;       # CoolInt-&gt;TIESCALAR($x); $x-&gt;STORE(42);</pre>
<p>Thus making it transparent to the user, and not requiring either of
these:</p>
<pre>   # Use our constructor
   my $x = CoolInt-&gt;new(42);

   # Use a tie interface
   tie CoolInt $x;
   $x = 42;</pre>
<p>Finally, note that this RFC is not requiring that all builtin types use
the embedded <code>TIE</code> approach. :-)  Rather, <code>int</code> is just used as an
example because it's easy to understand.</p>
<a name='Assertion checking'></a><h2>Assertion checking</h2>
<p>With the above optimizations in place, it is quite possible for the
proposed <code>use strict 'types'</code> to take advantage of them and
automatically check that this:</p>
<pre>   use strict 'types';
   my int $x = 5.3;</pre>
<p>Should fail, simply by reading the optimizations from the <code>int</code> class
and checking them against the value being assigned to <code>$x</code>.</p>
<p>This becomes even more integrated with Piers' proposed <code>:isa</code> attribute
syntax:</p>
<pre>   use strict 'types';
   my Pet $spot :isa(any(qw/Dog Cat Llama/));
   $spot = new Camel;        # fail</pre>
<p>Now the compiler can check the type of <code>$spot</code> and verify the correct
thing is supposed to happen before its <code>STORE</code> method is even called.</p>
<a name='The :autotie attribute'></a><h2>The <code>:autotie</code> attribute</h2>
<p>In order to allow both autotied and other types of packages to easily
coexist, there needs to be a way to inform the compiler that this
package is providing an interface to automatically <code>tie</code> variables.</p>
<p>To do this, we add an <code>:autotie</code> attribute that can be specified on the
package:</p>
<pre>   package Pet :autotie;     # package will be auto-tied</pre>
<p>This tells the compiler that any <code>my</code> or <code>our</code> declarations using
this package as a type should result in that package's <code>TIE*</code> methods
being automatically invoked.</p>
<p>As such, if the package Pet provides a <code>TIESCALAR</code> but not a
<code>TIEARRAY</code> method, then the following:</p>
<pre>   my Pet @pets;</pre>
<p>Would result in an exception (same as with <code>tie</code> currently).</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<a name='The mild version'></a><h2>The mild version</h2>
<p>In this version, <code>tie</code> is implemented similarly to currently, only
hopefully faster because of vtable stuff getting stuck in SV's. If you
made it possible to inherit from builtin variable types like <code>int</code> and
<code>float</code>, then this RFC would work pretty well. It would amount to
basically a robust coat of sugar to make <code>tie</code>d classes look like
builtin types.</p>
<a name='The over-the-top version'></a><h2>The over-the-top version</h2>
<p>When taking this to its logical extreme, the idea is that the name of
the method used to store data <b>is</b> <code>STORE</code>, even internally. Instead
of <code>mg.c</code> having to call special functions and make special checks,
<code>STORE</code> is called, whatever that <code>STORE</code> may be. If a variable is of
type <code>Pet</code>, then that class's <code>STORE</code> is used, which may in fact be
inherited from <code>Mammal</code>. Thus OO inheritance is embedded and fast.</p>
<p>This would only really work if the proposed embedded vtable stuff in
Perl 6 was not dog slow. In fact, it would only work if the dispatch
mechanism for this type of thing becomes really fast. If vtable stuff is
embedded from the ground up, and all data stuff is implemented this way,
it might be possible.</p>
<a name='MIGRATION'></a><h1>MIGRATION</h1>
<p>This should be transparent if implemented correctly, and should not
require migration.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>RFC 200: Objects: Revamp tie to support extensibility (Massive tie changes)</p>
<p>RFC 279: my() syntax extensions and attribute declarations</p>
<p>RFC 303: Keep <code>use less</code>, but make it work.</p>
<p>RFC 337: Common attribute system to allow user-defined, extensible attributes</p>
<p>RFC 265: Interface polymorphism considered lovely</p>
<p>RFC 218: <code>my Dog $spot</code> is just an assertion</p>
<p>RFC 137: Overview: Perl OO should <i>not</i> be fundamentally changed.</p>
<p>RFC 161: Everything in Perl becomes an object.</p>
<p>RFC 270: Replace XS with the <code>Inline</code> module as the standard way to extend Perl.</p>
</div>
